<template>
  <div id="container">
    <div id="coordinate" class="coordinateC" style="" v-if="this.$store.state.currentFrameNameStore === 'cesium'">
      <p><span>【相机】</span>
        姿态：<span class="span1">{{cameraOrientation.heading}}&nbsp&nbsp{{cameraOrientation.pitch}}&nbsp&nbsp{{cameraOrientation.roll}}</span>
        &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp
        位置：<span>{{cameraPositiontoDegrees.lon}}&nbsp&nbsp{{cameraPositiontoDegrees.lat}}&nbsp&nbsp{{cameraPositiontoDegrees.height}}</span>
      </p>
    </div>
    <div id="coordinate2" class="coordinateC" style="" v-if="this.$store.state.currentFrameNameStore === 'leaflet'">
      <p><span>【状态】</span>
        鼠标：<span>{{cameraPositiontoDegrees.lon}}&nbsp&nbsp{{cameraPositiontoDegrees.lat}}</span>
        &nbsp&nbsp&nbsp&nbsp
        中心：<span class="span1">{{cameraOrientation.heading}}&nbsp&nbsp{{cameraOrientation.pitch}}&nbsp&nbsp{{cameraOrientation.roll}}</span>
        &nbsp&nbsp&nbsp&nbsp
        缩放：{{cameraPositiontoDegrees.height}}
        &nbsp&nbsp&nbsp&nbsp
        地图：{{mapName}}
      </p>
    </div>
    <div class="my-toolbar">
      <button type="button" class="my" title="二三维" @click="switchMapFrame()">
        <img src="../data/image/双模式切换.svg" style="display: block; width: 22px; height: 22px; margin: auto">
      </button>
      <button type="button" class="my" title="加载JSON" @click="loadGeoJson()">
        <img src="../data/image/添加数据.svg" style="display: block; width: 22px; height: 22px; margin: auto">
      </button>
      <div style="display: flex;align-items: center;flex-direction: row-reverse">
        <button type="button" class="my" id="clear-selected" title="清除数据" @click="clearButtonOn()">
          <img src="../data/image/清除数据.svg" style="display: block; width: 22px; height: 22px; margin: auto">
        </button>
        <div style="display: flex;flex-direction: row-reverse" v-if="this.onClearButton">
          <button type="button" class="my my-font" title="清除数据" @click="removeAllLayer">清除所有
          </button>
          <button type="button" class="my my-font" title="清除数据" @click="">清除标记
          </button>
          <button type="button" class="my my-font" title="清除数据" @click="removeAllJson">清除json
          </button>
        </div>

      </div>
      <button type="button" class="my" title="测试功能" @click="test()">
        <img src="../data/image/测试.svg" style="display: block; width: 28px; height: 28px; margin: auto">
      </button>
    </div>
    <div id="mapContainer"></div>
    <input type="file" id="files" ref="refFile" style="display: none" v-on:change="fileLoad">
  </div>
</template>

<script>
  // import baseMap from "./function/baseMap";
  import {getJsMethod} from "../script/utils/common"
  import {eventBus, Gisevevts} from "../script/events";

  export default {
    name: "mapContainer",
    props: {},
    data() {
      return {
        // currentLayer:Object,
        msg: 'Welcome to Your Vue.js App',
        cameraPositiontoDegrees: {
          lon: 8,
          lat: 8,
          height: 8
        },
        cameraOrientation: {
          heading: 8,
          pitch: 8,
          roll: 8
        },
        rectangle: Object,
        onClearButton: false,//清除数据按钮关闭
        mapName: '',//地图名字
        geoJsonLayerArray: [],//加载的geojson图层统一管理
      }
    },
    computed: {
      monitoringFrameName() {
        // console.log("就算一下haha");
        return this.$store.state.currentFrameNameStore;
      }
    },
    created() {//页面渲染前，即通常初始化某些属性值，然后再渲染成视图
      //下面这行，说明created能拿到store的值
      // console.log("看一下是否拿到了数据：" + this.$store.state.name + this.$store.state.count);
      //下面这行，说明可以正常调用methods
      // this.justTest01();
    },
    mounted() {//页面渲染完成后
      getJsMethod("initMap").then(e => {
        e(this.$store.state.currentFrameNameStore);
        this.initRender();
      });
      eventBus.$on(Gisevevts["handlerMapFrameSwitch"], () => {
        this.switchMapFrame();
        this.initRender();
      });
      eventBus.$on(Gisevevts["handlerReloadMapFrame"], (e) => {
        this.mapName = e;
        this.initRender();
      });
      eventBus.$on(Gisevevts["handlerAddGeojson"], (e) => {
        this.addGeojson(e);//geoJsonLayerArray
      });
    },
    methods: {
      removeAllLayer() {
        // leafletMap.eachLayer((layer) => {
        //   leafletMap.removeLayer(layer);
        // });

        //移除除底图外的所有图层
        leafletMap.eachLayer(function (layer) {
          if (!layer._container || ('' + jQuery(layer._container).attr('class')).replace(/\s/g, '') != 'leaflet-layer') {
            layer.remove();
          }
        });

        //移除除底图+marker点外的所有图层
        // for(var i in leafletMap._layers) {
        //   if(leafletMap._layers[i]._path != undefined) {
        //     try {
        //       leafletMap.removeLayer(leafletMap._layers[i]);
        //     }
        //     catch(e) {
        //       console.log("problem with " + e + leafletMap._layers[i]);
        //     }
        //   }
        // }
      },
      removeAllJson() {
        this.geoJsonLayerArray.forEach((item) => {
          leafletMap.removeLayer(item);
        });
        this.geoJsonLayerArray = [];
        console.log("清空");
      },
      addGeojson(layer) {
        console.log("添加了一个json层");
        if (this.$store.state.currentFrameNameStore === 'leaflet') {
          this.geoJsonLayerArray.push(layer);
        }
      },
      justTest01() {
        console.log("justTest01");
      },
      test() {
        this.$store.commit("increment", "哈哈");
      },
      clearButtonOn() {
        this.onClearButton = !this.onClearButton;
        if ($("#clear-selected").hasClass("my-selected")) {
          $("#clear-selected").removeClass("my-selected");
        } else {
          $("#clear-selected").addClass("my-selected");
        }
      },
      loadGeoJson() {
        this.$refs.refFile.dispatchEvent(new MouseEvent('click'));
      },
      fileLoad() {
        //获取读取的文件File对象 下面两种方法实现效果一样
        //方法一:原生html获取
        // const selectedFile = document.getElementById('files').files[0];
        //方法二:Vue实现
        let selectedFile = this.$refs.refFile.files[0];
        let name = selectedFile.name; //选中文件的文件名
        let size = selectedFile.size; //选中文件的大小（单位b）
        // console.log("文件名:" + name + "大小:" + size);
        //判断文件是否为shp文件
        let extension = name.split('.')[1];
        if('shp'=== extension){
          this.loadShp(selectedFile)
        } else if ('json' === extension){
          this.loadJson(selectedFile,name)
        }else {
          this.$message.error("请选择后缀为'shp'或'json'的文件")
        }
        let obj = document.getElementById('files');
        obj.value = '';
      },
      loadJson(file,name){
        let reader = new FileReader();
        reader.readAsText(file);
        reader.onload = (result) => {
          if (!this.isJSONStr(result.target.result)) {
            return this.$message.error("该文件的GeoJSON格式有误")
          }
          this.$message.success("正在加载: " + name);
          getJsMethod("loadGeoJson").then(e => e($.parseJSON(result.target.result)));
        }
      },
      loadShp(file){
        //加载shp会丢失属性信息（或许可以同时读取dbf的文件，再赋值）
        //参考https://blog.csdn.net/yuban12315/article/details/86663061?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control
        let reader = new FileReader();
        //将文件以二进制形式读入页面
        reader.readAsArrayBuffer(file);
        // reader.readAsText(file);
        reader.onload = function () {
          let fileData = this.result; //fileData就是读取到的文件的二进制数据
          /*
            shapefile.open(https://cdn.rawgit.com/mbostock/shapefile/master/test/points.shp)
            {"type":"GeometryCollection", "geometries": [...  也可以
           */
          let gisleung = shapefile.open(this.result)//
            .then(source => source.read()
              .then(function log(result) {
                //这是一个循环，每个循环体输出一个要素的GeoJSON格式
                if (result.done) return;
                console.log(result.value);
                // this.$message.success("正在加载: " + 'shp文件');
                getJsMethod("loadGeoJson").then(e => e(result.value));
                return source.read().then(log);
              }))
            .catch(error => console.error(error.stack));
          console.log(gisleung)
        }
      },
      isJSONStr(str) {
        if (typeof str == 'string') {
          try {
            let obj = JSON.parse(str);
            return !!(typeof obj == 'object' && obj);
          } catch (e) {
            // console.log('error：' + str + '!!!' + e);
            return false;
          }
        }
        // console.log('It is not a string!')
      },
      switchMapFrame() {
        let tempFrame = this.$store.state.currentFrameNameStore === 'cesium' ? ('leaflet') : ('cesium');
        this.unloadMapFrame(this.$store.state.currentFrameNameStore);
        setTimeout(() => {
          this.loadMapFrame(tempFrame);
        }, 100);
      },
      //卸载当前的地图框架
      unloadMapFrame() {
        getJsMethod("getRectangle").then(e => {
          this.rectangle = e();
          getJsMethod("unloadMapFrame").then(e => e());
          this.hasFrame = false;
        });
      },
      loadMapFrame(loadMap) {
        this.$store.state.currentFrameNameStore = loadMap;
        getJsMethod("initMap").then(e => {
          e(loadMap);
          this.initRender();
          getJsMethod("setRectangle").then(e => e(this.rectangle));
        });
      },
      initRender() {
        if (this.$store.state.currentFrameNameStore === "cesium") {
          this.postRenderAdd(this.handler);
        } else if (this.$store.state.currentFrameNameStore === "leaflet") {
          leafletMap.whenReady(() => {
            this.cameraPositiontoDegrees.height = leafletMap.getZoom();
            this.cameraOrientation.heading = leafletMap.getCenter().lng.toFixed(3);
            this.cameraOrientation.pitch = leafletMap.getCenter().lat.toFixed(3);
            this.cameraOrientation.roll = '';
          });
          leafletMap.on('mousemove', this.onMapClick);
          leafletMap.on('zoomend', this.onZoomEnd);
          leafletMap.on('move', this.onMove);
        }
      },
      onMapClick(e) {
        this.cameraPositiontoDegrees.lon = e.latlng.lng.toFixed(3);
        this.cameraPositiontoDegrees.lat = e.latlng.lat.toFixed(3);
      },
      onZoomEnd() {
        this.cameraPositiontoDegrees.height = leafletMap.getZoom();
      },
      onMove() {
        this.cameraOrientation.heading = leafletMap.getCenter().lng.toFixed(3);
        this.cameraOrientation.pitch = leafletMap.getCenter().lat.toFixed(3);
        this.cameraOrientation.roll = '';
      },
      handler() {
        let camera = viewer.camera;
        try { //切换二三维的时候，会出错
          this.cameraOrientation.heading = Cesium.Math.toDegrees(camera.heading).toFixed(4);
          this.cameraOrientation.pitch = Cesium.Math.toDegrees(camera.pitch).toFixed(4);
          this.cameraOrientation.roll = Cesium.Math.toDegrees(camera.roll).toFixed(4);
        } catch (e) {
        }

        //三维视图下，这两个一样，可以正常转经纬度。二维情况下cartographic_1的获取的不太对
        let cartographic_1 = Cesium.Cartographic.fromCartesian(camera.position);
        let cartographic = viewer.camera.positionCartographic;

        this.cameraPositiontoDegrees.lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(3);
        this.cameraPositiontoDegrees.lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(3);
        this.cameraPositiontoDegrees.height = cartographic.height.toFixed(3);
      },

      postRenderAdd(theHandler) {
        viewer.scene.postRender.addEventListener(theHandler);
      },
    },
    watch: {
      monitoringFrameName(newVal, oldValue) {
        console.log("地图框架从：" + oldValue + "变为" + newVal);
      }
    },

  }
</script>

<style scoped>
  .my-toolbar {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: flex-end;
    position: absolute;
    z-index: 200;
    bottom: 50%;
    right: 5px;
    width: auto;
    transform: translateY(50%);
  }

  .my {
    display: inline-block;
    position: relative;
    background: #303336;
    border: 1px solid #444;
    color: #edffff;
    fill: #edffff;
    margin: 2px 3px 2px 3px;
    cursor: pointer;
    overflow: hidden;
    user-select: none;
    box-sizing: border-box;
    width: 32px;
    height: 32px;
    border-radius: 14%;
    padding: 0;
    vertical-align: middle;
    z-index: 0;
  }

  .my-selected {
    border-color: #2e2;
    box-shadow: 0 0 8px #fff, 0 0 8px #fff;
  }

  .my-font {
    font-size: 12px;
    text-align: center;
    line-height: 14px;
  }

  .my:hover {
    color: #fff;
    fill: #fff;
    background: #48b;
    border-color: #aef;
    -webkit-box-shadow: 0 0 8px #fff;
    box-shadow: 0 0 8px #fff;
  }

  .my:active {
    color: #000;
    fill: #000;
    background: #adf;
    border-color: #fff;
    -webkit-box-shadow: 0 0 8px #fff;
    box-shadow: 0 0 8px #fff;
  }

  .my:focus {
    color: #fff;
    fill: #fff;
    border-color: #ea4;
    outline: none;
  }

  .coordinateC {
    position: absolute;
    white-space: nowrap;
    border-radius: 10px;
    top: 3px;
    left: 50%;
    transform: translateX(-50%);
    height: 30px;
    width: fit-content;
    color: honeydew;
    z-index: 100;
    background-color: #2c3e50;
    margin: 3px;
    margin-left: 100px;
  }

  .coordinateC p {
    line-height: 30px;
    margin-top: 0px;
    margin-right: 10px;
    margin-left: 10px;
  }

  .coordinateC p {
    line-height: 30px;
    margin-top: 0px;
    margin-right: 10px;
    margin-left: 10px;
  }

  #container, #mapContainer {
    width: 100%;
    height: 100%;
  }
</style>
